package br.com.werp.regras.sequenciador;

import br.com.werp.regras.geral.ErroPadrao;
import br.com.werp.regras.geral.GerenciadorErros;
import br.com.werp.regras.geral.Sequenciador;
import br.com.werp.regras.geral.util.Constantes;
import br.com.werp.regras.sequenciador.controle.ControleSequencia;
import br.com.werp.regras.sequenciador.integracao.FabricaDAO;
import br.com.werp.regras.sequenciador.integracao.SequenciaDAO;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;


/**
 * @author Sobreira
 * Created on 27/09/2004
 */
public class SequenciadorImpl implements Sequenciador {
    public static final ResourceBundle bundle =
        ResourceBundle.getBundle(Constantes.CONFIG);
    private static SequenciadorImpl sequenciadorImpl;
    private ControleSequencia controleSequencia = new ControleSequencia();

    private SequenciadorImpl() {
    }

    public static SequenciadorImpl getSequenciadorImpl() {
        if (sequenciadorImpl == null) {
            sequenciadorImpl = new SequenciadorImpl();
        }

        return sequenciadorImpl;
    }

    /* (non-Javadoc)
     * @see br.com.werp.regras.geral.Sequenciador#obterProximoId(java.lang.String)
     */
    public int obterProximoId(String sequenciadorNome)
        throws ErroPadrao {
        try {
            return controleSequencia.obterProximoId(sequenciadorNome);
        } catch (Exception e) {
            throw new ErroPadrao(GerenciadorErros.logarErro(e));
        }
    }

    public static void main(String[] args) throws Exception {
        FabricaDAO.getSequenciaDAO();

        Map data = new HashMap();
        data.put("lista", new ArrayList());
        data.put("erros", new ArrayList());
        for (int i = 0; i < 30; i++) {
            SequenciadorImpl impl = new SequenciadorImpl();
            Class.forName(bundle.getString("DBDRIVER"));
            Connection connection =
                DriverManager.getConnection(bundle.getString("DBURL"),
                    bundle.getString("DBUSER"), bundle.getString("DBPASS"));
            SequenceThread thread = impl.new SequenceThread(data,i,connection);
            thread.start();
            //Thread.sleep((long) ((Math.random() + 1) * 1000));
        }

        Thread.sleep(90000);
        System.out.println("Loop");

        List ids = (List) data.get("lista");
        List erros = (List) data.get("erros");
        System.out.println(ids);
        System.out.println("total :" + ids.size());
        System.out.println("erros :" + erros.size());
        System.out.println(erros);
    }

    //classe privada para testes...
    private class SequenceThread extends Thread {
        public Map data = null;
        private int id = 0; 
        private Connection connection;
        /**
        * @param connection 
         * @param ids
        */
        public SequenceThread(Map data,int id, Connection connection) {
            super();
            this.data = data;
            this.id=id;
            this.connection = connection;
        }

        public void run() {
            super.run();

            SequenciaDAO sequenciaDAO;

            try {
                sequenciaDAO = FabricaDAO.getSequenciaDAO();

                List ids = (List) data.get("lista");
                List erros = (List) data.get("erros");

                for (int i = 0; i < 50; i++) {
                    Integer val = null;

                    try {
                        String seq = "PROCEDIMENTO";
                        val = new Integer(sequenciaDAO.obterProximoId(seq,connection));
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    System.out.println("Thread num " + id + " pegou val = "+val);
                    if ((val != null) && !ids.contains(val)) {
                        ids.add(val);
                    } else if (val != null) {
                        erros.add(val);
                    }

                    sleep(150);
                }
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }
}
